package br.com.socialfut.helper;

/*
 * The Android chronometer widget revised so as to count milliseconds
 */

import java.text.DecimalFormat;

import android.content.Context;
import android.media.MediaPlayer;
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
import android.util.AttributeSet;
import android.widget.TextView;
import br.com.socialfut.R;
import br.com.socialfut.util.Constants;

public class Chronometer extends TextView
{

    private int maxTime;

    private long mBase;

    private boolean mVisible;

    private boolean mStarted;

    private boolean mRunning;

    private OnChronometerTickListener mOnChronometerTickListener;

    private long timeWhenStopped = 0;

    private static final int TICK_WHAT = 2;

    private long timeElapsed;

    private Context context;

    public interface OnChronometerTickListener
    {
        void onChronometerTick(Chronometer chronometer);
    }

    public void setMaxTime(int maxTime)
    {
        this.maxTime = maxTime;
    }

    public Chronometer(Context context)
    {
        this(context, null, 0);
    }

    public Chronometer(Context context, AttributeSet attrs)
    {
        this(context, attrs, 0);
    }

    public Chronometer(Context context, AttributeSet attrs, int defStyle)
    {
        super(context, attrs, defStyle);
        this.context = context;
        init();
    }

    private void init()
    {
        mBase = SystemClock.elapsedRealtime();
        updateText(mBase);
    }

    public void setBase(long base)
    {
        mBase = base;
        dispatchChronometerTick();
        updateText(mBase);
    }

    public long getBase()
    {
        return mBase;
    }

    public void setOnChronometerTickListener(OnChronometerTickListener listener)
    {
        mOnChronometerTickListener = listener;
    }

    public OnChronometerTickListener getOnChronometerTickListener()
    {
        return mOnChronometerTickListener;
    }

    public void start()
    {
        mBase = SystemClock.elapsedRealtime();
        mStarted = true;
        updateRunning();
    }

    public void resume()
    {
        mBase = SystemClock.elapsedRealtime() + timeWhenStopped;
        mStarted = true;
        updateRunning();
    }

    public void pause()
    {
        timeWhenStopped = getBase() - SystemClock.elapsedRealtime();
        mStarted = false;
        updateRunning();
    }

    public void stopForTime()
    {
        mStarted = false;
        Constants.TIME = 0;
        updateRunning();
        playSound();
    }

    public void reset()
    {
        mStarted = false;
        timeWhenStopped = 0;
        setBase(SystemClock.elapsedRealtime());
        updateRunning();
    }

    public void setStarted(boolean started)
    {
        mStarted = started;
        updateRunning();
    }

    @Override
    protected void onDetachedFromWindow()
    {
        super.onDetachedFromWindow();
        mVisible = false;
        updateRunning();
    }

    @Override
    protected void onWindowVisibilityChanged(int visibility)
    {
        super.onWindowVisibilityChanged(visibility);
        mVisible = visibility == VISIBLE;
        updateRunning();
    }

    private synchronized void updateText(long now)
    {
        timeElapsed = now - mBase;

        DecimalFormat df = new DecimalFormat("00");

        int hours = (int) (timeElapsed / (3600 * 1000));
        int remaining = (int) (timeElapsed % (3600 * 1000));

        int minutes = (int) (remaining / (60 * 1000));
        remaining = (int) (remaining % (60 * 1000));

        int seconds = (int) (remaining / 1000);
        remaining = (int) (remaining % (1000));

        int milliseconds = (int) (((int) timeElapsed % 1000) / 100);

        String text = "";

        if (hours > 0)
        {
            text += df.format(hours) + ":";
        }

        text += df.format(minutes) + ":";
        text += df.format(seconds) + ":";
        text += Integer.toString(milliseconds);

        setText(text);
    }

    private void updateRunning()
    {
        boolean running = mVisible && mStarted;
        if (running != mRunning)
        {
            if (running)
            {
                dispatchChronometerTick();
                mHandler.sendMessageDelayed(Message.obtain(mHandler, TICK_WHAT), 100);
            }
            else
            {
                mHandler.removeMessages(TICK_WHAT);
            }
            mRunning = running;
        }
    }

    private Handler mHandler = new Handler()
    {
        public void handleMessage(Message m)
        {
            if (mRunning)
            {
                if (hasToStop(SystemClock.elapsedRealtime()))
                {
                    stopForTime();
                }
                else
                {
                    updateText(SystemClock.elapsedRealtime());
                    dispatchChronometerTick();
                    sendMessageDelayed(Message.obtain(this, TICK_WHAT), 100);
                }
            }
        }
    };

    void dispatchChronometerTick()
    {
        if (mOnChronometerTickListener != null)
        {
            mOnChronometerTickListener.onChronometerTick(this);
        }
    }

    public long getTimeElapsed()
    {
        return timeElapsed;
    }

    private boolean hasToStop(long mBase)
    {
        long elapsedMillis = mBase - getBase();

        return elapsedMillis >= maxTime;

        // if (elapsedMillis >= maxTime)
        // {
        // return true;
        // }
        // return false;
    }

    private void playSound()
    {
        MediaPlayer mediaPlayer = MediaPlayer.create(context, R.drawable.whistle);
        mediaPlayer.start();
    }

}